home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Pascal / Applications / Flight Stability / Flight Stability Source / CFSAircraftPane.p < prev    next >
Encoding:
Text File  |  1995-07-05  |  17.0 KB  |  298 lines  |  [TEXT/PJMM]

  1. {****************************************************}
  2. {}
  3. {        CFSAircraftPane.p                                                                                                                                                                                    }
  4. {}
  5. {        Pane methods for the aircraft pane.                                                                                                                                    }
  6. {}
  7. {        Copyright © 1995, Patrick Hew.  All rights reserved.                                                                            }
  8. {}
  9. {****************************************************}
  10.  
  11.  
  12. unit CFSAircraftPane;
  13.  
  14. interface
  15.  
  16.     uses
  17.         TCL, FSIntf;
  18.  
  19. implementation
  20.  
  21.  
  22. { PerspectiveProjection }
  23. {}
  24. { Returns: The projection of aPoint onto the plane with origin aPlaneOrigin and }
  25. {   axes aAxis1 and aAxis2, where the eye point is at aEyeDist from aPlaneOrigin }
  26. {   in the direction aAxis1 x aAxis2. That is, we look from aEyeDist along }
  27. {   aAxis1 x aAxis2 through aPlaneOrigin. }
  28. { Reference: Taken from Section 16.2 of: }
  29. {  "Computer Graphics - An Introduction to the Mathematics and Geometry" }
  30. {  by M E Mortenson, published by Industrial Press, NY, 1989. }
  31. {  Actually, I think that the z coordinate after projection is a bit bogus, but as it }
  32. {  is probably never used, it is unlikely to really matter. }
  33.  
  34.     function PerspectiveProjection (aPoint, aCentreOfProjection, aAxis1, aAxis2: V3Type; aEyeDist: Real): V3Type;
  35.  
  36.         var
  37.             u1, u2, u3: V3Type;
  38.             pointOffset: V3Type;
  39.             depthScale: Real;
  40.  
  41.     begin { PerspectiveProjection }
  42.         u1 := V3Normalized(aAxis1);
  43.         u2 := V3Normalized(aAxis2);
  44.         u3 := V3CrossProduct(u1, u2);
  45.  
  46.         pointOffset := V3Diff(aPoint, aCentreOfProjection);
  47.         depthScale := V3DotProduct(pointOffset, u3) - aEyeDist;
  48.  
  49.         PerspectiveProjection := V3Scale(-aEyeDist / depthScale, V3FromScalars(V3DotProduct(pointOffset, u1), V3DotProduct(pointOffset, u2), 1));
  50.     end; { PerspectiveProjection }
  51.  
  52.  
  53. { IFSAircraftPane }
  54. {}
  55. { Post: The aircraft pane has been initialized. }
  56.  
  57.     procedure CFSAircraftPane.IFSAircraftPane (anEnclosure: CView; aSupervisor: CBureaucrat; aWidth, aHeight, aHEncl, aVEncl: integer; aHSizing, aVSizing: SizingOption);
  58.  
  59.     begin { IFSAircraftPane }
  60.         IPane(anEnclosure, aSupervisor, aWidth, aHeight, aHEncl, aVEncl, aHSizing, aVSizing);
  61.  
  62.         fuselageTopLeft[1] := V3FromScalars(-200, 40, 40);
  63.         fuselageTopLeft[2] := V3FromScalars(200, 40, 40);
  64.         fuselageTopLeft[3] := V3FromScalars(220, 60, 0);
  65.         fuselageTopLeft[4] := V3FromScalars(-200, 60, 0);
  66.  
  67.         fuselageTopRight[1] := V3FromScalars(-200, -40, 40);
  68.         fuselageTopRight[2] := V3FromScalars(-200, -60, 0);
  69.         fuselageTopRight[3] := V3FromScalars(220, -60, 0);
  70.         fuselageTopRight[4] := V3FromScalars(200, -40, 40);
  71.  
  72.         fuselageTopCentre[1] := fuselageTopLeft[1];
  73.         fuselageTopCentre[2] := fuselageTopRight[1];
  74.         fuselageTopCentre[3] := fuselageTopRight[4];
  75.         fuselageTopCentre[4] := fuselageTopLeft[2];
  76.  
  77.         noseCentre[1] := V3FromScalars(700, 0, 0);
  78.         noseCentre[2] := fuselageTopCentre[4];
  79.         noseCentre[3] := fuselageTopCentre[3];
  80.  
  81.         noseLeft[1] := fuselageTopLeft[2];
  82.         noseLeft[2] := noseCentre[1];
  83.         noseLeft[3] := fuselageTopLeft[3];
  84.  
  85.         noseRight[1] := fuselageTopRight[3];
  86.         noseRight[2] := noseCentre[1];
  87.         noseRight[3] := fuselageTopRight[4];
  88.  
  89.         cockpitFront[1] := V3FromScalars(360, 20, 30);
  90.         cockpitFront[2] := V3FromScalars(280, 20, 80);
  91.         cockpitFront[3] := V3FromScalars(280, -20, 80);
  92.         cockpitFront[4] := V3FromScalars(360, -20, 30);
  93.  
  94.         cockpitBack[1] := cockpitFront[2];
  95.         cockpitBack[2] := V3FromScalars(200, 20, 40);
  96.         cockpitBack[3] := V3FromScalars(200, -20, 40);
  97.         cockpitBack[4] := cockpitFront[3];
  98.  
  99.         fuselageBottomLeft[1] := V3FromScalars(-200, 40, -40);
  100.         fuselageBottomLeft[2] := fuselageTopLeft[4];
  101.         fuselageBottomLeft[3] := V3FromScalars(160, 60, 0);
  102.         fuselageBottomLeft[4] := V3FromScalars(160, 40, -40);
  103.  
  104.         fuselageBottomRight[1] := V3FromScalars(-200, -40, -40);
  105.         fuselageBottomRight[2] := V3FromScalars(160, -40, -40);
  106.         fuselageBottomRight[3] := V3FromScalars(160, -60, 0);
  107.         fuselageBottomRight[4] := fuselageTopRight[2];
  108.  
  109.         fuselageBottomCentre[1] := fuselageBottomLeft[1];
  110.         fuselageBottomCentre[2] := fuselageBottomLeft[4];
  111.         fuselageBottomCentre[3] := fuselageBottomRight[2];
  112.         fuselageBottomCentre[4] := fuselageBottomRight[1];
  113.  
  114.         intake[1] := fuselageBottomLeft[3];
  115.         intake[2] := fuselageBottomRight[3];
  116.  
  117.         leftWing[1] := V3FromScalars(180, 60, 0);
  118.         leftWing[2] := V3FromScalars(0, 320, 0);
  119.         leftWing[3] := V3FromScalars(-40, 320, 0);
  120.         leftWing[4] := V3FromScalars(-40, 60, 0);
  121.  
  122.         rightWing[1] := V3FromScalars(180, -60, 0);
  123.         rightWing[2] := V3FromScalars(-40, -60, 0);
  124.         rightWing[3] := V3FromScalars(-40, -320, 0);
  125.         rightWing[4] := V3FromScalars(0, -320, 0);
  126.  
  127.         leftTail[1] := V3FromScalars(-100, 60, 0);
  128.         leftTail[2] := V3FromScalars(-160, 160, 0);
  129.         leftTail[3] := V3FromScalars(-180, 160, 0);
  130.         leftTail[4] := V3FromScalars(-180, 60, 0);
  131.  
  132.         rightTail[1] := V3FromScalars(-100, -60, 0);
  133.         rightTail[2] := V3FromScalars(-180, -60, 0);
  134.         rightTail[3] := V3FromScalars(-180, -160, 0);
  135.         rightTail[4] := V3FromScalars(-160, -160, 0);
  136.  
  137.         tailFin[1] := V3FromScalars(-180, 0, 40);
  138.         tailFin[2] := V3FromScalars(-180, 0, 200);
  139.         tailFin[3] := V3FromScalars(-140, 0, 200);
  140.         tailFin[4] := V3FromScalars(0, 0, 40);
  141.     end; { IFSAircraftPane }
  142.  
  143.  
  144. { UpdateAircraft }
  145. {}
  146. { Post: The bank and AOA have been updated. This effects the local }
  147. {   coordinate change from absolute to aircraft, although this }
  148. {   implementation does not use this fact. }
  149. { Note: We should really do this by sending a message to the aircraft }
  150. {   itself, rather than the pane, but this is a hack. }
  151.  
  152.     procedure CFSAircraftPane.UpdateAircraft (aBank, aAOA: Real);
  153.  
  154.     begin { UpdateAircraft }
  155.         itsBank := aBank;
  156.         itsAOA := aAOA;
  157.  
  158.         { Always refresh. }
  159.         Refresh;
  160.     end; { UpdateAircraft }
  161.  
  162.  
  163. { Draw }
  164. {}
  165. { Post: The aircraft has been drawn. We draw a wireframe. }
  166. {   For some reason, backface elimination is unreliable with }
  167. {   perspective projection. }
  168.  
  169.     const
  170.         kCentreh = kAircraftPaneLenh div 2;
  171.         kCentrev = kAircraftPaneLenv div 2;
  172.  
  173.     procedure CFSAircraftPane.Draw (var area: Rect);
  174.  
  175.         var
  176.             theBankMatrix, theAOAMatrix: M3Type;
  177.  
  178.             { We will need to store up to 6 projected points at once. }
  179.             { Kludge! Kludge! Kludge! :) }
  180.             theArrayIndex: Integer;
  181.             theProjectionStore: array[1..6] of Point;
  182.             theProjection: V3Type;
  183.  
  184.             theCentreOfProjection, theAxis1, theAxis2: V3Type;
  185.             theEyeDist: Real;
  186.  
  187.  
  188.     begin { Draw }
  189.         { We pitch the aircraft around the y axis and roll around the x. }
  190.         { Note that this will give the same result for pitch-roll and roll-pitch, }
  191.         { though of course in real life this is not the case. }
  192.  
  193.         { The camera in absolute space is fixed, and is as follows. }
  194.         theAxis1 := V3FromScalars(0, -1, 0);
  195.         theAxis2 := V3FromScalars(1, 0, 4);
  196.         theCentreOfProjection := V3FromScalars(-400, 0, 100);
  197.         theEyeDist := 200;
  198.  
  199.         { Note that for the aircraft, positive bank is a positive rotation about }
  200.         { the x axis, and positive pitch is a negative rotation about the y axis. }
  201.         { Further note that we map the aircraft by this amount, so the }
  202.         { transition matrices are the inverse. }
  203.         theBankMatrix := RotX(-itsBank);
  204.         theAOAMatrix := RotY(itsAOA);
  205.  
  206.         { Left of nose. }
  207.         for theArrayIndex := 1 to 3 do begin
  208.             theProjection := PerspectiveProjection(M3TimesV3(theBankMatrix, M3TimesV3(theAOAMatrix, noseLeft[theArrayIndex])), theCentreOfProjection, theAxis1, theAxis2, theEyeDist);
  209.             theProjectionStore[theArrayIndex].h := kCentreh + Trunc(theProjection.row[1]);
  210.             theProjectionStore[theArrayIndex].v := kCentrev - Trunc(theProjection.row[2]);
  211.         end; { for }
  212.         MoveTo(theProjectionStore[3].h, theProjectionStore[3].v);
  213.         for theArrayIndex := 1 to 3 do begin
  214.             LineTo(theProjectionStore[theArrayIndex].h, theProjectionStore[theArrayIndex].v);
  215.         end; { for }
  216.  
  217.         { Centre of nose. }
  218.         for theArrayIndex := 1 to 3 do begin
  219.             theProjection := PerspectiveProjection(M3TimesV3(theBankMatrix, M3TimesV3(theAOAMatrix, noseCentre[theArrayIndex])), theCentreOfProjection, theAxis1, theAxis2, theEyeDist);
  220.             theProjectionStore[theArrayIndex].h := kCentreh + Trunc(theProjection.row[1]);
  221.             theProjectionStore[theArrayIndex].v := kCentrev - Trunc(theProjection.row[2]);
  222.         end; { for }
  223.         MoveTo(theProjectionStore[3].h, theProjectionStore[3].v);
  224.         for theArrayIndex := 1 to 3 do begin
  225.             LineTo(theProjectionStore[theArrayIndex].h, theProjectionStore[theArrayIndex].v);
  226.         end; { for }
  227.  
  228.         { Right of nose. }
  229.         for theArrayIndex := 1 to 3 do begin
  230.             theProjection := PerspectiveProjection(M3TimesV3(theBankMatrix, M3TimesV3(theAOAMatrix, noseRight[theArrayIndex])), theCentreOfProjection, theAxis1, theAxis2, theEyeDist);
  231.             theProjectionStore[theArrayIndex].h := kCentreh + Trunc(theProjection.row[1]);
  232.             theProjectionStore[theArrayIndex].v := kCentrev - Trunc(theProjection.row[2]);
  233.         end; { for }
  234.         MoveTo(theProjectionStore[3].h, theProjectionStore[3].v);
  235.         for theArrayIndex := 1 to 3 do begin
  236.             LineTo(theProjectionStore[theArrayIndex].h, theProjectionStore[theArrayIndex].v);
  237.         end; { for }
  238.  
  239.         { Front of cockpit. }
  240.         for theArrayIndex := 1 to 4 do begin
  241.             theProjection := PerspectiveProjection(M3TimesV3(theBankMatrix, M3TimesV3(theAOAMatrix, cockpitFront[theArrayIndex])), theCentreOfProjection, theAxis1, theAxis2, theEyeDist);
  242.             theProjectionStore[theArrayIndex].h := kCentreh + Trunc(theProjection.row[1]);
  243.             theProjectionStore[theArrayIndex].v := kCentrev - Trunc(theProjection.row[2]);
  244.         end; { for }
  245.         MoveTo(theProjectionStore[4].h, theProjectionStore[4].v);
  246.         for theArrayIndex := 1 to 4 do begin
  247.             LineTo(theProjectionStore[theArrayIndex].h, theProjectionStore[theArrayIndex].v);
  248.         end; { for }
  249.  
  250.         { Back of cockpit. }
  251.         for theArrayIndex := 1 to 4 do begin
  252.             theProjection := PerspectiveProjection(M3TimesV3(theBankMatrix, M3TimesV3(theAOAMatrix, cockpitBack[theArrayIndex])), theCentreOfProjection, theAxis1, theAxis2, theEyeDist);
  253.             theProjectionStore[theArrayIndex].h := kCentreh + Trunc(theProjection.row[1]);
  254.             theProjectionStore[theArrayIndex].v := kCentrev - Trunc(theProjection.row[2]);
  255.         end; { for }
  256.         MoveTo(theProjectionStore[4].h, theProjectionStore[4].v);
  257.         for theArrayIndex := 1 to 4 do begin
  258.             LineTo(theProjectionStore[theArrayIndex].h, theProjectionStore[theArrayIndex].v);
  259.         end; { for }
  260.  
  261.         { Top left of fuselage. }
  262.         for theArrayIndex := 1 to 4 do begin
  263.             theProjection := PerspectiveProjection(M3TimesV3(theBankMatrix, M3TimesV3(theAOAMatrix, fuselageTopLeft[theArrayIndex])), theCentreOfProjection, theAxis1, theAxis2, theEyeDist);
  264.             theProjectionStore[theArrayIndex].h := kCentreh + Trunc(theProjection.row[1]);
  265.             theProjectionStore[theArrayIndex].v := kCentrev - Trunc(theProjection.row[2]);
  266.         end; { for }
  267.         MoveTo(theProjectionStore[4].h, theProjectionStore[4].v);
  268.         for theArrayIndex := 1 to 4 do begin
  269.             LineTo(theProjectionStore[theArrayIndex].h, theProjectionStore[theArrayIndex].v);
  270.         end; { for }
  271.  
  272.         { Top centre of fuselage. }
  273.         for theArrayIndex := 1 to 4 do begin
  274.             theProjection := PerspectiveProjection(M3TimesV3(theBankMatrix, M3TimesV3(theAOAMatrix, fuselageTopCentre[theArrayIndex])), theCentreOfProjection, theAxis1, theAxis2, theEyeDist);
  275.             theProjectionStore[theArrayIndex].h := kCentreh + Trunc(theProjection.row[1]);
  276.             theProjectionStore[theArrayIndex].v := kCentrev - Trunc(theProjection.row[2]);
  277.         end; { for }
  278.         MoveTo(theProjectionStore[4].h, theProjectionStore[4].v);
  279.         for theArrayIndex := 1 to 4 do begin
  280.             LineTo(theProjectionStore[theArrayIndex].h, theProjectionStore[theArrayIndex].v);
  281.         end; { for }
  282.  
  283.         { Top right of fuselage. }
  284.         for theArrayIndex := 1 to 4 do begin
  285.             theProjection := PerspectiveProjection(M3TimesV3(theBankMatrix, M3TimesV3(theAOAMatrix, fuselageTopRight[theArrayIndex])), theCentreOfProjection, theAxis1, theAxis2, theEyeDist);
  286.             theProjectionStore[theArrayIndex].h := kCentreh + Trunc(theProjection.row[1]);
  287.             theProjectionStore[theArrayIndex].v := kCentrev - Trunc(theProjection.row[2]);
  288.         end; { for }
  289.         MoveTo(theProjectionStore[4].h, theProjectionStore[4].v);
  290.         for theArrayIndex := 1 to 4 do begin
  291.             LineTo(theProjectionStore[theArrayIndex].h, theProjectionStore[theArrayIndex].v);
  292.         end; { for }
  293.  
  294.         { Bottom left of fuselage. }
  295.         for theArrayIndex := 1 to 4 do begin
  296.             theProjection := PerspectiveProjection(M3TimesV3(theBankMatrix, M3TimesV3(theAOAMatrix, fuselageBottomLeft[theArrayIndex])), theCentreOfProjection, theAxis1, theAxis2, theEyeDist);
  297.             theProjectionStore[theArrayIndex].h := kCentreh + Trunc(theProjection.row[1]);
  298.             theProjectionStore[theArrayIndex].v := kCentrev - Tr